<template>
  <!-- 添加或修改角色配置对话框 -->
  <el-dialog :title="title" :visible.sync="visible" width="500px" append-to-body :close-on-click-modal="false" @closed="reset">
    <el-form ref="form" :model="form" :rules="rules" label-width="80px">
      <el-form-item label="角色名称" prop="roleName">
        <el-input v-model="form.roleName" placeholder="请输入角色名称"/>
      </el-form-item>
      <el-form-item label="权限字符" prop="roleKey">
        <el-input v-model="form.roleKey" placeholder="请输入权限字符"/>
      </el-form-item>
      <el-form-item label="角色顺序" prop="roleSort">
        <el-input-number v-model="form.roleSort" controls-position="right" :min="0"/>
      </el-form-item>
      <el-form-item label="状态">
        <el-radio-group v-model="form.status">
          <el-radio
            v-for="dict in statusOptions"
            :key="dict.dictValue"
            :label="dict.dictValue">
            {{dict.dictLabel}}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单权限">
        <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event)">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event)">全选/全不选</el-checkbox>
        <el-tree
          class="tree-border"
          :data="menuOptions"
          show-checkbox
          ref="menu"
          node-key="id"
          :check-strictly="true"
          empty-text="加载中，请稍后"
          :props="defaultProps">
        </el-tree>
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" :loading="submitting" @click="submitForm">确 定</el-button>
      <el-button @click="close">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { addRole, getRole, updateRole, roleSelectedMenu } from "@/api/system/role";
import { getMenuTree } from "@/api/system/menu";

export default {
  name: "edit",
  props: {
    statusOptions: {
      type: Array,
      default: []
    }
  },
  data() {
    return {
      id: undefined,
      title: "新增编辑",
      visible: false,
      submitting: false,
      menuExpand: false,
      menuNodeAll: false,
      menuOptions: [],
      defaultProps: {
        children: "children",
        label: "label"
      },
      // 表单参数
      form: {
        roleName: undefined,
        roleKey: undefined,
        roleSort: 0,
        status: "0",
        menuIds: [],
        remark: undefined
      },
      // 表单校验
      rules: {
        roleName: [
          { required: true, message: "角色名称不能为空", trigger: "blur" }
        ],
        roleKey: [
          { required: true, message: "权限字符不能为空", trigger: "blur" }
        ],
        roleSort: [
          { required: true, message: "角色顺序不能为空", trigger: "blur" }
        ]
      }
    }
  },
  methods: {
    init(id, title) {
      this.visible = true;
      this.id = id;
      this.title = title;
      this.initMenuTree();
      if (id) {
        this.initData();
      }
    },
    initData() {
      getRole(this.id).then(response => {
        this.form = response;
      });
    },
    /** 查询菜单树结构 */
    initMenuTree() {
      getMenuTree({
        systemNames: undefined
      }).then(response => {
        this.menuOptions = response;

        if (this.id) {
          roleSelectedMenu(this.id).then(res => {
            const menuIds = [];
            this.$lodash.each(res, item => {
              menuIds.push(item.menuId);
            });
            this.$refs.menu.setCheckedKeys(menuIds);
          });
        }
      });
    },
    close() {
      this.visible = false;
    },
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.form.menuIds = this.getMenuAllCheckedKeys();

          this.submitting = true;
          if (this.id) {
            updateRole(this.id, this.form).then(response => {
              this.submitting = false;

              this.msgSuccess("修改成功");
              this.close();
              this.$emit('success');
            }).catch(() => {
              this.submitting = false;
            });
          } else {
            addRole(this.form).then(response => {
              this.submitting = false;

              this.msgSuccess("新增成功");
              this.close();
              this.$emit('success');
            }).catch(() => {
              this.submitting = false;
            });
          }
        }
      });
    },
    // 表单重置
    reset() {
      if (this.$refs.menu !== undefined) {
        this.$refs.menu.setCheckedKeys([]);
      }
      this.menuExpand = false;
      this.menuNodeAll = false;
      this.menuOptions = [];
      this.id = undefined;
      this.form = {
        roleName: undefined,
        roleKey: undefined,
        roleSort: 0,
        status: "0",
        menuIds: [],
        remark: undefined
      };
      this.resetForm("form");
    },
    // 树权限（展开/折叠）
    handleCheckedTreeExpand(value) {
      let treeList = this.menuOptions;
      let allMenuIds = [];
      this.getAllMenuIds(treeList, allMenuIds);
      this.expandedAll(allMenuIds, value);
    },
    getAllMenuIds(treeList, allMenuIds) {
      if (treeList && treeList.length > 0) {
        this.$lodash.each(treeList, item => {
          allMenuIds.push(item.id);
          const children = item.children;
          this.getAllMenuIds(children, allMenuIds);
        });
      }
    },
    expandedAll(allMenuIds, value) {
      this.$lodash.each(allMenuIds, item => {
        this.$refs.menu.store.nodesMap[item].expanded = value;
      });
    },
    // 树权限（全选/全不选）
    handleCheckedTreeNodeAll(value) {
      let allMenuIds = [];
      if (value) {
        this.getAllMenuIds(this.menuOptions, allMenuIds);
      }
      this.$refs.menu.setCheckedKeys(allMenuIds);
    },
    // 所有菜单节点数据
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.menu.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      return checkedKeys;
    }
  }
}
</script>

<style scoped>
.tree-border {
  max-height: 300px;
  overflow-y: auto;
}
</style>
